#if !defined(BOSTREAM_H)
#define BOSTREAM_H

#include <ostream>
#include <string>
#include <vector>
#include <list>
#include "biotypes.h"

namespace xtd {

template<class E, class Tr = std::char_traits<E> >
	class basic_bostream : public std::basic_ostream<E, Tr> {
	typedef basic_bostream<E, Tr> bostream; 
public:
// construction/destruction
    explicit basic_bostream(std::basic_streambuf<E, Tr> * buf) : std::basic_ostream<E, Tr>(buf) {}
    virtual ~basic_bostream() {}
// inserters
    template <class T> bostream & put(const T & x) {
		const int REM = sizeof(T) % sizeof(E);	// remainder
        const int SIZE = sizeof(T) / sizeof(E) + (REM ? 1 : 0); // ceil
/*#if !defined __GNUC__ && !defined __BORLANDC__
		if (REM) {
			union { T value; E bytes[SIZE]; } u;
			u.value = x; // copying!
			write(u.bytes, SIZE);
		} else {
#endif
*/			write(reinterpret_cast<const E *>(& x), SIZE);
/*#if !defined __GNUC__ && !defined __BORLANDC__
		}
#endif*/
        return * this;
    } 
    bostream & operator << (bool x)
        { return put(x); }
    bostream & operator << (signed short int x)
        { return put(x); }
    bostream & operator << (unsigned short int x)
        { return put(x); }
    bostream & operator << (signed int x)          
        { return put(x); }
    bostream & operator << (unsigned int x)          
        { return put(x); }
    bostream & operator << (signed long int x)     
        { return put(x); }
    bostream & operator << (unsigned long int x)     
        { return put(x); }
    bostream & operator << (signed char x)         
        { return put(x); }
    bostream & operator << (unsigned char x)         
        { return put(x); }
    bostream & operator << (float x) 
        { return put(x); }
    bostream & operator << (double x) 
        { return put(x); }
    bostream & operator << (long double x) 
        { return put(x); }
    bostream & operator << (const void * x) 
        { return put(x); }
};
             
typedef basic_bostream<char, std::char_traits<char> > bostream;

inline bostream & operator << (bostream & out, const char * x) { 
	int32u len = static_cast<int32u>(strlen(x));
	out << len; 
	out.write(x, len);
	return out;
}

inline bostream & operator << (bostream & out, const std::string & x) {
	int32u len = static_cast<int32u>(x.length());
	out << len; 
	out.write(x.c_str(), len);
	return out;
}

template <class C>
bostream & write_container(bostream & out, const C & c) {
	out << int32u(c.size());
	typename C::const_iterator i;
	for (i = c.begin(); i != c.end(); ++i)
		out << *i;
	return out;
}

template <class T>
inline bostream & operator << (bostream & out, const std::vector<T> & x) 
	{ return write_container(out, x); }

template <class T>
inline bostream & operator << (bostream & out, const std::list<T> & x) 
	{ return write_container(out, x); }

} // xtd

#endif // !defined(BOSTREAM_H)
